/**
 * $version:  0.1 
 * $Date: 2011-01-21 
 *
 * Copyright (C) 2010-2011 Jawa Software. All rights reserved.
 *
 */

package org.jawa.admin.util;

import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

import org.jawa.auth.AuthToken;
import org.jawa.branch.BranchManager;
import org.jawa.core.JawaServer;
import org.jawa.core.cache.Cache;
import org.jawa.core.cache.CacheFactory;
import org.jawa.core.util.JawaGlobals;
import org.jawa.exam.question.QuestionManager;
import org.jawa.user.User;
import org.jawa.user.UserManager;

/**
 * 页面管理工具类.
 */
public class WebManager extends WebBean {

	private int range = 15;

	public WebManager() {
	}

	/**
	 * Returns the XMPP server object -- can get many config items from here.
	 */
	public JawaServer getJawaServer() {
		final JawaServer jawaServer = JawaServer.getInstance();
		if (jawaServer == null) {
			// Show that the server is down
			return null;
		}
		return jawaServer;
	}

	/**
	 * Returns the name of the application.
	 * 
	 * @return the name of the application.
	 */
	public static String getAppName() {
		String appName = JawaGlobals.getXMLProperty("global.appName");
		if (appName != null) {
			return appName;
		}
		return null;
	}

	/**
	 * Returns the URL of the main logo image for the admin console.
	 * 
	 * @return the logo image.
	 */
	public static String getLogoImage() {
		String globalLogoImage = JawaGlobals.getXMLProperty("global.logoImage");
		if (globalLogoImage != null) {
			return globalLogoImage;
		}
		return null;
	}

	/**
	 * Returns the URL of the login image for the admin console.
	 * 
	 * @return the login image.
	 */
	public static String getLoginLogoImage() {
		String globalLogoImage = JawaGlobals.getXMLProperty("global.loginImage");
		if (globalLogoImage != null) {
			return globalLogoImage;
		}
		return null;
	}

	/**
	 * 可能有问题，请参考原来实现
	 * @return the version string.
	 */
	public static String getVersionString() {
		return JawaServer.getInstance().getVersion().getVersionString();
	}

	/**
	 * Returns <tt>true</tt> if the Openfire container is in setup mode,
	 * <tt>false</tt> otherwise.
	 */
	public boolean isSetupMode() {
		return getJawaServer().isSetupMode();
	}

	public boolean isServerRunning() {
		return !(getJawaServer() == null);
	}

	/**
	 * Returns the auth token redirects to the login page if an auth token is not found.
	 */
	public AuthToken getAuthToken() {
		return (AuthToken) session.getAttribute("jawa.admin.authToken");
	}

	/**
	 * 返回当前页面的用户.
	 */
	public User getUser() {
		User pageUser = null;
		try {
			pageUser = UserManager.getInstance().getUserByUsername(getAuthToken().getUsername());
		} catch (Exception ignored) {
			// 忽略.
		}
		return pageUser;
	}

	/**
	 * 记录当前登录用户的安全事件,用于审计。
	 *
	 * @param summary 事件标题.
	 * @param details 事件详情.
	 */
	public void logEvent(String summary, String details) {
		// SecurityAuditManager.getInstance().logEvent(getUser().getUsername(), summary, details);
	}

	/**
	 * Returns the number of rows per page for the specified page for the current logged user.
	 * The rows per page value is stored as a user property. The same property is being used for
	 * different pages. The encoding format is the following "pageName1=value,pageName2=value".
	 *
	 * @param pageName     the name of the page to look up its stored value.
	 * @param defaultValue the default value to return if no user value was found.
	 * @return the number of rows per page for the specified page for the current logged user.
	 */
	public int getRowsPerPage(String pageName, int defaultValue) {
		return getPageProperty(pageName, "console.rows_per_page", defaultValue);
	}

	/**
	 * Sets the new number of rows per page for the specified page for the current logged user.
	 * The rows per page value is stored as a user property. The same property is being used for
	 * different pages. The encoding format is the following "pageName1=value,pageName2=value".
	 *
	 * @param pageName the name of the page to stored its new value.
	 * @param newValue the new rows per page value.
	 */
	public void setRowsPerPage(String pageName, int newValue) {
		setPageProperty(pageName, "console.rows_per_page", newValue);
	}

	/**
	 * Returns the number of seconds between each page refresh for the specified page for the
	 * current logged user. The value is stored as a user property. The same property is being
	 * used for different pages. The encoding format is the following
	 * "pageName1=value,pageName2=value".
	 *
	 * @param pageName     the name of the page to look up its stored value.
	 * @param defaultValue the default value to return if no user value was found.
	 * @return the number of seconds between each page refresh for the specified page for
	 *         the current logged user.
	 */
	public int getRefreshValue(String pageName, int defaultValue) {
		return getPageProperty(pageName, "console.refresh", defaultValue);
	}

	/**
	 * Sets the number of seconds between each page refresh for the specified page for the
	 * current logged user. The value is stored as a user property. The same property is being
	 * used for different pages. The encoding format is the following
	 * "pageName1=value,pageName2=value".
	 *
	 * @param pageName the name of the page to stored its new value.
	 * @param newValue the new number of seconds between each page refresh.
	 */
	public void setRefreshValue(String pageName, int newValue) {
		setPageProperty(pageName, "console.refresh", newValue);
	}

	public int getPageProperty(String pageName, String property, int defaultValue) {
		User user = getUser();
		if (user != null) {
			String values = user.getProperties().get(property);
			if (values != null) {
				StringTokenizer tokens = new StringTokenizer(values, ",=");
				while (tokens.hasMoreTokens()) {
					String page = tokens.nextToken().trim();
					String rows = tokens.nextToken().trim();
					if (pageName.equals(page)) {
						try {
							return Integer.parseInt(rows);
						} catch (NumberFormatException e) {
							return defaultValue;
						}
					}
				}
			}
		}
		return defaultValue;
	}

	public void setPageProperty(String pageName, String property, int newValue) {
		String toStore = pageName + "=" + newValue;
		User user = getUser();
		if (user != null) {
			String values = user.getProperties().get(property);
			if (values != null) {
				if (values.contains(toStore)) {
					// The new value for the page was already stored so do nothing
					return;
				} else {
					if (values.contains(pageName)) {
						// Replace an old value for the page with the new value
						int oldValue = getPageProperty(pageName, property, -1);
						String toRemove = pageName + "=" + oldValue;
						user.getProperties().put(property, values.replace(toRemove, toStore));
					} else {
						// Append the new page-value
						user.getProperties().put(property, values + "," + toStore);
					}
				}
			} else {
				// Store the new page-value as a new user property
				user.getProperties().put(property, toStore);
			}
		}
	}

	/**
	 * 返回分页情况下的当前页码(目前适用于使用DisplayTag的情况).
	 * 
	 * @return 当前页码
	 */
	public int getPageIndex(int pageRange,String pageId) {
		int pageIndex = 0;
		String pageNumberName = new org.displaytag.util.ParamEncoder(pageId)
				.encodeParameterName(org.displaytag.tags.TableTagParameters.PARAMETER_PAGE); // 页数的参数名
		int pageNumber = org.apache.commons.lang.StringUtils.isEmpty(request.getParameter(pageNumberName)) ? 1
				: (Integer.parseInt(request.getParameter(pageNumberName))); // 当前页数

		pageIndex = (pageNumber - 1) * pageRange;

		return pageIndex;
	}

	private void sleep() {
		try {
			Thread.sleep(3000L);
		} catch (Exception ignored) {
			// 忽略.
		}
	}

	public Cache[] getCaches() {
		Cache[] caches = CacheFactory.getAllCaches();
		Arrays.sort(caches, new Comparator<Cache>() {
			public int compare(Cache cache1, Cache cache2) {
				return cache1.getName().toLowerCase().compareTo(cache2.getName().toLowerCase());
			}
		});
		return caches;
	}

	public WebManager getManager() {
		return this;
	}

	/**
	 * see {@link JawaServer#getUserManager()}
	 * @return UserManager 实例
	 */
	public UserManager getUserManager() {
		return UserManager.getInstance();
	}
	
	/**
	 * see {@link JawaServer#getBranchManager()}
	 * @return BranchManager 实例
	 */
	public BranchManager getBranchManager() {
		return BranchManager.getInstance();
	}
	
	/**
	 * @return QuestionManager 实例
	 */
	public QuestionManager getQuestionManager() {
		return QuestionManager.getInstance();
	}
}